'''
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License") you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http:#www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
'''
from numbers import Number

from base.datatypes import TypeMapper
from base.exception.PropertyNotFoundException import PropertyNotFoundException
from base.graph.GraphUtil import GraphUtil
from base.graph.Node import Node
from base.graph.NodeFactory import NodeFactory
from base.java.Class import Class
from base.java.exception.NullPointerException import NullPointerException
from base.java.exception.UnsupportedOperationException import UnsupportedOperationException
from base.rdf.Model import Model
from base.rdf.Resource import Resource
from base.rdf.impl.IteratorFactory import IteratorFactory
from base.rdf.impl.LiteralImpl import LiteralImpl
from base.rdf.impl.RDFReaderFImpl import RDFReaderFImpl
from base.rdf.impl.RDFWriterFImpl import RDFWriterFImpl

from base.rdf.impl.Util import Util
from base.shared.JenaException import JenaException
from base.shared.PrefixMapping import PrefixMapping
from base.sys.JenaSystem import JenaSystem

#import java.io.*;
#import java.net.URL;
#import java.util.*;
#import java.util.function.Supplier;

#import org.apache.jena.datatypes.DatatypeFormatException;
#import org.apache.jena.datatypes.RDFDatatype;
#import org.apache.jena.datatypes.TypeMapper;
#import org.apache.jena.datatypes.xsd.XSDDatatype;
#import org.apache.jena.datatypes.xsd.XSDDateTime;
#import org.apache.jena.enhanced.BuiltinPersonalities;
#import org.apache.jena.enhanced.EnhGraph;
#import org.apache.jena.enhanced.Personality;
#import org.apache.jena.graph.*;
#import org.apache.jena.graph.impl.LiteralLabel;
#import org.apache.jena.graph.impl.LiteralLabelFactory;
#import org.apache.jena.rdf.model.*;
#import org.apache.jena.shared.*;
#import org.apache.jena.shared.impl.PrefixMappingImpl;
#import org.apache.jena.sys.JenaSystem;
#import org.apache.jena.util.CollectionFactory;
#import org.apache.jena.util.iterator.ClosableIterator;
#import org.apache.jena.util.iterator.ExtendedIterator;
#import org.apache.jena.util.iterator.FilterIterator;
#import org.apache.jena.util.iterator.Map1Iterator;
#import org.apache.jena.vocabulary.RDF;

'''
 * Common methods for model implementations.
 *
 * <P>This class implements common methods, mainly convenience methods, for
 * model implementations.  It is intended use is as a base class from which
 * model implementations can be derived.</P>
'''

# RDFReaderF
readerFactory = RDFReaderFImpl()
# RDFWriterF
writerFactory = RDFWriterFImpl()

# 继承Lock EnhGraph
class ModelCom(Model, PrefixMapping):

    # static:
        # This forces RIOT (in ARQ) to initialize but after Jena readers/writers
        # have cleanly initialized from the calls of RDFReaderFImpl and RDFWriterFImpl
        # above.  RIOT initialization happens before model.read can be called.

    

    '''
     * make a model based on the specified graph
    '''
    # param Graph base:
    def __init__(self, base):
        JenaSystem.init()
        self.graph = base
        #this(base, BuiltinPersonalities.model)
    

    # param Graph base, Personality<RDFNode> personality:
    # def __init__(self, basePersonality<RDFNode>):
    #     super().__init__(base, personality)
    

    ##@Override
    # param 
    # result Graph
    def getGraph(self):
        return self.graph
    

    # param 
    # result static Model
    @staticmethod
    def createWorkModel():
        from base.rdf.ModelFactory import ModelFactory
        return ModelFactory.createDefaultModel()
    

    ##@Override
    # param Node n
    # result RDFNode
    # def asRDFNode(self, n):
    #     return n.isLiteral()
    #             ? (RDFNode) self.getNodeAs(n, Literal.class)
    #             : (RDFNode) self.getNodeAs(n, Resource.class)
    

    ##@Override
    # param Node n
    # result Resource
    def wrapAsResource(self, n):
        if (n.isLiteral()):
            raise UnsupportedOperationException("literal cannot be converted to Resource")
        return self.getNodeAs(n, Class(Resource))
    

    '''
     * the ModelReifier does everything to do with reification.
    '''
    # param this
    # result ModelReifier modelReifier = new
    #def ModelReifier modelReifier = new ModelReifier(self)

    ##@Override
    ##@Deprecated
    # param String uri, ResourceF f
    # result Resource
    # def getResource(self, uri, f):
    #     try:
    #         return f.createResource(self.getResource(uri))
    #     except Exception as e:
    #         raise JenaException(e)
        
    

    ##@Override
    # param Resource s, Property p, boolean o
    # result Model
    # def addLiteral(self, s, p, o):
    #     return add(s, p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Resource s, Property p, long o
    # # result Model
    # def addLiteral(self, s, p, o):
    #     return add(s, p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Resource s, Property p, int o
    # # result Model
    # def addLiteral(self, s, p, o):
    #     return add(s, p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Resource s, Property p, char o
    # # result Model
    # def addLiteral(self, s, p, o):
    #     return add(s, p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Resource s, Property p, float o
    # # result Model
    # def addLiteral(self, s, p, o):
    #     return add(s, p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Resource s, Property p, double o
    # # result Model
    # def addLiteral(self, s, p, o):
    #     return add(s, p, createTypedLiteral(o))
    

    ##@Override
    # param Resource s, Property p, String o
    # result Model
    # def add(self, s, p, o):
    #     pass
        #return add(s, p, o, "", False)
    

    ##@Override
    # param Resource s, Property p, String o, boolean wellFormed
    # result Model
    # def add(self, s, p, o, wellFormed):
    #     add(s, p, literal(o, "", wellFormed))
    #     return self
    

    # public Model add(Resource s, Property p, String o, String lang,
    #                  boolean wellFormed):
    #     add(s, p, literal(o, lang, wellFormed))
    #     return self
    

    ##@Override
    # param Resource s, Property p, String lex, RDFDatatype datatype
    # result Model
    # def add(self, s, p, lex, datatype):
    #     add(s, p, literal(lex, datatype))
    #     return self
    

    # param String s, String lang, boolean wellFormed
    # result Literal
    # def literal(self, s, lang, wellFormed):
    #     LiteralLabel ll = LiteralLabelFactory.create(s, lang, wellFormed)
    #     @SuppressWarnings("deprecation")
    #     Node n = NodeFactory.createLiteral(ll)
    #     return new LiteralImpl(n, this)
    

    # param String lex, RDFDatatype datatype
    # result Literal
    def literal(self, lex, datatype):
        return LiteralImpl(NodeFactory.createLiteral(lex, datatype), self)
    

    ##@Override
    # param Resource s, Property p, String o, String l
    # result Model
    # def add(self, s, p, o, l):
    #     return add(s, p, o, l, false)
    

    ##@Override
    ##@Deprecated
    # param Resource s, Property p, Object o
    # result Model
    # def addLiteral(self, s, p, o):
    #     return add(s, p, asObject(o))
    #
    #
    # ##@Override
    # # param Resource s, Property p, Literal o
    # # result Model
    # def addLiteral(self, s, p, o):
    #     return add(s, p, o)
    

    # param Object o
    # result RDFNode
    # def asObject(self, o):
    #     return o instanceof RDFNode ? (RDFNode) o : createTypedLiteral(o)
    

    ##@Override
    # param StmtIterator ite
    # result Model
    # def add(self, ite):
    #     try:
    #         GraphUtil.add(getGraph(), asTriples(ite))
    #      finally:
    #         ite.close()
    #
    #     return self
    

    ##@Override
    # param Model m
    # result Model
    # def add(self, m):
    #     GraphUtil.addInto(getGraph(), m.getGraph())
    #     return self
    

    ##@Override
    # param 
    # result RDFReaderI
    # def getReader(self):
    #     return readerFactory.getReader()
    

    ##@Override
    # param String lang
    # result RDFReaderI
    def getReader(self, lang):
        return readerFactory.getReader(lang)
    

    ##@Override
    # param String url
    # result Model
    # def read(self, url):
    #     readerFactory.getReader().read(this, url)
    #     return self
    #
    #
    # ##@Override
    # # param Reader reader, String base
    # # result Model
    # def read(self, reader, base):
    #     readerFactory.getReader().read(this, reader, base)
    #     return self
    #
    #
    # ##@Override
    # # param InputStream reader, String base
    # # result Model
    # def read(self, reader, base):
    #     readerFactory.getReader().read(this, reader, base)
    #     return self
    #
    #
    # ##@Override
    # # param String url, String lang
    # # result Model
    # def read(self, url, lang):
    #     readerFactory.getReader(lang).read(this, url)
    #     return self
    

    ##@Override
    # param String url, String base, String lang
    # result Model
    def read(self, url, base, lang):
        #TODO 后续只需要支持从文件读取就可以了
        pass
        # try (InputStream is = new URL(url).openStream()):
        #     read(is, base, lang)
        # catch (IOException e):
        #     raise WrappedIOException(e)
        #
        # return self
    

    ##@Override
    # param Reader reader, String base, String lang
    # result Model
    # def read(self, reader, base, lang):
    #     readerFactory.getReader(lang).read(this, reader, base)
    #     return self
    

    ##@Override
    # param InputStream reader, String base, String lang
    # result Model
    # def read(self, reader, base, lang):
    #     readerFactory.getReader(lang).read(this, reader, base)
    #     return self
    

    '''
     * Get the model's writer after priming it with the model's namespace
     * prefixes.
    '''
    ##@Override
    # param 
    # result RDFWriterI
    # def getWriter(self):
    #     return writerFactory.getWriter()
    

    '''
     * Get the model's writer after priming it with the model's namespace
     * prefixes.
    '''
    ##@Override
    # param String lang
    # result RDFWriterI
    def getWriter(self, lang):
        return writerFactory.getWriter(lang)
    

    ##@Override
    # param Writer writer
    # result Model
    # def write(self, writer):
    #     getWriter().write(this, writer, "")
    #     return self
    #
    #
    # ##@Override
    # # param Writer writer, String lang
    # # result Model
    # def write(self, writer, lang):
    #     getWriter(lang).write(this, writer, "")
    #     return self
    #
    #
    # ##@Override
    # # param Writer writer, String lang, String base
    # # result Model
    # def write(self, writer, lang, base):
    #     getWriter(lang).write(this, writer, base)
    #     return self
    #
    #
    # ##@Override
    # # param OutputStream writer
    # # result Model
    # def write(self, writer):
    #     getWriter().write(this, writer, "")
    #     return self
    #
    #
    # ##@Override
    # # param OutputStream writer, String lang
    # # result Model
    # def write(self, writer, lang):
    #     getWriter(lang).write(this, writer, "")
    #     return self
    

    ##@Override
    # param OutputStream writer, String lang, String base
    # result Model
    def write(self, writer, lang, base):
        #TODO 写到输出流中
        #getWriter(lang).write(self, writer, base)
        return self
    

    ##@Override
    # param Statement s
    # result Model
    # def remove(self, s):
    #     graph.delete(s.asTriple())
    #     return self
    

    ##@Override
    # param Resource s, Property p, RDFNode o
    # result Model
    def remove(self, s, p, o):
        #TODO 实现delete方法
        #graph.delete(Triple.create(s.asNode(), p.asNode(), o.asNode()))
        return self
    


    # ##@Override
    # # param StmtIterator ite
    # # result Model
    # def remove(self, ite):
    #     GraphUtil.delete(getGraph(), asTriples(ite))
    #     return self
    #
    #
    # ##@Override
    # # param Model m
    # # result Model
    # def remove(self, m):
    #     GraphUtil.deleteFrom(getGraph(), m.getGraph())
    #     return self
    

    ##@Override
    # param 
    # result Model
    def removeAll(self):
        #getGraph().clear()
        self.clear()
        return self
    

    ##@Override
    # param Resource s, Property p, RDFNode o
    # result Model
    # def removeAll(self, s, p, o):
    #     getGraph().remove(asNode(s), asNode(p), asNode(o))
    #     return self
    

    ##@Override
    # param Resource s, Property p, boolean o
    # result boolean
    def containsLiteral(self, s, p, o):
        #return self.contains(s, p, createTypedLiteral(o))
        return self.contains(s, p, self.createTypedLiteral(o))
    

    ##@Override
    # param Resource s, Property p, long o
    # result boolean
    # def containsLiteral(self, s, p, o):
    #     return self.contains(s, p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Resource s, Property p, int o
    # # result boolean
    # def containsLiteral(self, s, p, o):
    #     return self.contains(s, p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Resource s, Property p, char o
    # # result boolean
    # def containsLiteral(self, s, p, o):
    #     return self.contains(s, p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Resource s, Property p, float o
    # # result boolean
    # def containsLiteral(self, s, p, o):
    #     return self.contains(s, p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Resource s, Property p, double o
    # # result boolean
    # def containsLiteral(self, s, p, o):
    #     return self.contains(s, p, createTypedLiteral(o))
    

    ##@Override
    # param Resource s, Property p, String o
    # result boolean
    # def contains(self, s, p, o):
    #     return self.contains(s, p, o, "")
    

    ##@Override
    # param Resource s, Property p, String o, String lang
    # result boolean
    def contains(self, s, p, o, l):
        pass
        #TODO 实现统一的contains方法
        #return self.contains(s, p, self.literal(o, l, false))
    

    ##@Override
    # param Resource s, Property p, Object o
    # result boolean
    # def containsLiteral(self, s, p, o):
    #     return self.contains(s, p, asObject(o))
    

    ##@Override
    # param Model model
    # result boolean
    def containsAny(self, model):
        return self.containsAnyThenClose(model.listStatements())
    

    ##@Override
    # param Model model
    # result boolean
    def containsAll(self, model):
        return self.containsAllThenClose(model.listStatements())
    

    # param StmtIterator ite
    # result boolean
    def containsAnyThenClose(self, ite):
        try:
            return self.containsAny(ite)
        finally:
            ite.close()
        
    

    # param StmtIterator ite
    # result boolean
    def containsAllThenClose(self, ite):
        try:
            return self.containsAll(ite)
        finally:
            ite.close()
        
    

    ##@Override
    # param StmtIterator ite
    # result boolean
    # def containsAny(self, ite):
    #     while (ite.hasNext()) if (contains(ite.nextStatement())) return true
    #     return false
    

    ##@Override
    # param StmtIterator ite
    # result boolean
    # def containsAll(self, ite):
    #     while (ite.hasNext()) if (!contains(ite.nextStatement())) return false
    #     return true
    

    # param Resource S, Property P, Node O
    # result StmtIterator
    # def listStatements(self, S, P, O):
    #     return IteratorFactory.asStmtIterator
    #             (graph.find(asNode(S), asNode(P), O), this)
    

    ##@Override
    # param Resource S, Property P, RDFNode O
    # result StmtIterator
    def listStatements(self, S, P, O):
        #TODO
        pass
        #return listStatements(S, P, asNode(O))
    

    ##@Override
    # param Resource S, Property P, String O
    # result StmtIterator
    # def listStatements(self, S, P, O):
    #     return O == None ? listStatements(S, P, Node.ANY)
    #             : listStatements(S, P, NodeFactory.createLiteral(O))
    

    ##@Override
    # param Resource S, Property P, String O, String L
    # result StmtIterator
    # def listStatements(self, S, P, O, L):
    #     if (O != None):
    #         # this is not OK when L is None: returns only the statements whose lang is ""
    #         # return listStatements( S, P, Node.createLiteral( O, L, false ) )
    #         if (L != None) return listStatements(S, P, NodeFactory.createLiteral(O, L))
    #         # there's maybe a better way
    #         return new StringFilteredStmtIterator(O, listStatements(S, P, Node.ANY))
    #      else:
    #         return new LangFilteredStmtIterator(L, listStatements(S, P, Node.ANY))
        
    

    # private class StringFilteredStmtIterator extends FilterIterator<Statement>
    #         implements StmtIterator:
    #     public StringFilteredStmtIterator(final String str, Iterator<Statement> it):
    #         super().__init__(s ->:
    #             RDFNode o = s.getObject()
    #             if (o instanceof Literal):
    #                 if (str == None)
    #                     return true # should not happen
    #                 return (str.equals(o.asLiteral().getString()))
    #
    #             return false
    #         , it)
        

        ##@Override
    # param 
    # result Statement
    # def nextStatement(self):
    #     return next()
        
    

    # private class LangFilteredStmtIterator extends FilterIterator<Statement> implements StmtIterator:
    #     public LangFilteredStmtIterator(final String l, Iterator<Statement> it):
    #         super().__init__(s ->:
    #             RDFNode o = s.getObject()
    #             if (o instanceof Literal):
    #                 if (l == None)
    #                     return true
    #                 return (l.equals(o.asLiteral().getLanguage()))
    #
    #             return false
    #         , it)
        

        ##@Override
    # param 
    # result Statement
    # def nextStatement(self):
    #         return next()
        
    


    ##@Override
    # param Resource S, Property P, boolean O
    # result StmtIterator
    # def listLiteralStatements(self, S, P, O):
    #     return listStatements(S, P, createTypedLiteral(O))
    

    ##@Override
    # param Resource S, Property P, long O
    # result StmtIterator
    # def listLiteralStatements(self, S, P, O):
    #     return listStatements(S, P, createTypedLiteral(O))
    #
    #
    # ##@Override
    # # param Resource S, Property P, int O
    # # result StmtIterator
    # def listLiteralStatements(self, S, P, O):
    #     return listStatements(S, P, createTypedLiteral(O))
    #
    #
    # ##@Override
    # # param Resource S, Property P, char O
    # # result StmtIterator
    # def listLiteralStatements(self, S, P, O):
    #     return listStatements(S, P, createTypedLiteral(O))
    #
    #
    # ##@Override
    # # param Resource S, Property P, float O
    # # result StmtIterator
    # def listLiteralStatements(self, S, P, O):
    #     return listStatements(S, P, createTypedLiteral(O))
    #
    #
    # ##@Override
    # # param Resource S, Property P, double O
    # # result StmtIterator
    # def listLiteralStatements(self, S, P, O):
    #     return listStatements(S, P, createTypedLiteral(O))
    

    '''
         list resources with property [was: list subjects with property]
    '''

    ##@Override
    # param Property p, boolean o
    # result ResIterator
    def listResourcesWithProperty(self, p, o):
        #TODO
        pass
        #return listResourcesWithProperty(p, createTypedLiteral(o))
    

    ##@Override
    # param Property p, char o
    # result ResIterator
    # def listResourcesWithProperty(self, p, o):
    #     return listResourcesWithProperty(p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Property p, long o
    # # result ResIterator
    # def listResourcesWithProperty(self, p, o):
    #     return listResourcesWithProperty(p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Property p, float o
    # # result ResIterator
    # def listResourcesWithProperty(self, p, o):
    #     return listResourcesWithProperty(p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Property p, double o
    # # result ResIterator
    # def listResourcesWithProperty(self, p, o):
    #     return listResourcesWithProperty(p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Property p, Object o
    # # result ResIterator
    # def listResourcesWithProperty(self, p, o):
    #     return listResourcesWithProperty(p, createTypedLiteral(o))
    

    ##@Override
    # param Property p, RDFNode o
    # result ResIterator
    def listSubjectsWithProperty(self, p, o):
        pass
        #TODO
        #return listResourcesWithProperty(p, o)
    

    ##@Override
    # param Property p, String o
    # result ResIterator
    # def listSubjectsWithProperty(self, p, o):
    #     return listSubjectsWithProperty(p, o, "")
    #
    #
    # ##@Override
    # # param Property p, String o, String l
    # # result ResIterator
    # def listSubjectsWithProperty(self, p, o, l):
    #     return listResourcesWithProperty(p, literal(o, l, false))
    

    ##@Override
    # param Resource type
    # result Resource
    # def createResource(self, type):
    #     return self.createResource().addProperty(RDF.type, type)
    

    ##@Override
    # param String uri, Resource type
    # result Resource
    # def createResource(self, uri, type):
    #     return getResource(uri).addProperty(RDF.type, type)
    #
    #
    # ##@Override
    # ##@Deprecated
    # # param ResourceF f
    # # result Resource
    # def createResource(self, f):
    #     return self.createResource(None, f)
    #
    #
    # ##@Override
    # # param AnonId id
    # # result Resource
    # def createResource(self, id):
    #     return new ResourceImpl(id, this)
    #
    #
    # ##@Override
    # # param Statement statement
    # # result Resource
    # def createResource(self, statement):
    #     return new ResourceImpl(statement, this)
    #
    #
    # ##@Override
    # ##@Deprecated
    # # param String uri, ResourceF f
    # # result Resource
    # def createResource(self, uri, f):
    #     return f.createResource(createResource(uri))
    #


    '''
     * create a type literal from a boolean value.
     *
     * <p> The value is converted to a string using its <CODE>toString</CODE>
     * method. </p>
     *
     * @param v the value of the literal
     * @return a new literal representing the value v
    '''
    # @Override
    # param boolean v
    # result Literal
    def createTypedLiteral(self, v):
        # if isinstance(v, bool):
        #     pass
        # elif isinstance(v, int):
        #     pass
        # elif isinstance(v, float):
        #     pass
        # RDFDatatype
        # TODO 关注这个方法是否能成功
        dt = TypeMapper.getInstance().getTypeByValue(v)
        return NodeFactory.createLiteralByValue(v, "", dt)
    

    '''
     * create a typed literal from an integer value.
     *
     * @param v the value of the literal
     * @return a new literal representing the value v
    '''
    ##@Override
    # param int v
    # result Literal
    # def createTypedLiteral(self, v):
    #     return self.createTypedLiteral(Integer.valueOf(v))
    #
    #
    # '''
    #  * create a typed literal from a long integer value.
    #  *
    #  * @param v the value of the literal
    #  * @return a new literal representing the value v
    # '''
    # ##@Override
    # # param long v
    # # result Literal
    # def createTypedLiteral(self, v):
    #     return self.createTypedLiteral(Long.valueOf(v))
    #
    #
    # '''
    #  * create a typed literal from a char value.
    #  *
    #  * @param v the value of the literal
    #  * @return a new literal representing the value v
    # '''
    # ##@Override
    # # param char v
    # # result Literal
    # def createTypedLiteral(self, v):
    #     return self.createTypedLiteral(Character.valueOf(v))
    #
    #
    # '''
    #  * create a typed literal from a float value.
    #  *
    #  * @param v the value of the literal
    #  * @return a new literal representing the value v
    # '''
    # ##@Override
    # # param float v
    # # result Literal
    # def createTypedLiteral(self, v):
    #     return self.createTypedLiteral(Float.valueOf(v))
    #
    #
    # '''
    #  * create a typed literal from a double value.
    #  *
    #  * @param v the value of the literal
    #  * @return a new literal representing the value v
    # '''
    # ##@Override
    # # param double v
    # # result Literal
    # def createTypedLiteral(self, v):
    #     return self.createTypedLiteral(Double.valueOf(v))
    #
    #
    # '''
    #  * create a typed literal from a String value.
    #  *
    #  * @param v the value of the literal
    #  * @return a new literal representing the value v
    # '''
    # ##@Override
    # # param String v
    # # result Literal
    # def createTypedLiteral(self, v):
    #     LiteralLabel ll = LiteralLabelFactory.createTypedLiteral(v)
    #     return new LiteralImpl(NodeFactory.createLiteral(v), this)
    #
    #
    # '''
    #  * Create a typed literal xsd:dateTime from a Calendar object.
    # '''
    # ##@Override
    # # param Calendar cal
    # # result Literal
    # def createTypedLiteral(self, cal):
    #     Object value = new XSDDateTime(cal)
    #     LiteralLabel ll = LiteralLabelFactory.createByValue(value, "", XSDDatatypeInstances.XSDdateTime)
    #     @SuppressWarnings("deprecation")
    #     Node n = NodeFactory.createLiteral(ll)
    #     return new LiteralImpl(n, this)
    #
    #
    #
    # '''
    #  * Build a typed literal from its lexical form. The
    #  * lexical form will be parsed now and the value stored. If
    #  * the form is not legal this will throw an exception.
    #  *
    #  * @param lex   the lexical form of the literal
    #  * @param dtype the type of the literal, None for old style "plain" literals
    #  * @throws DatatypeFormatException if lex is not a legal form of dtype
    # '''
    # ##@Override
    # # param String lex, RDFDatatype dtype
    # # result Literal
    # def createTypedLiteral(self, lex, dtype)
    #         throws DatatypeFormatException:
    #     return new LiteralImpl(NodeFactory.createLiteral(lex, dtype), this)
    #
    #
    # '''
    #  * Build a typed literal from its value form.
    #  *
    #  * @param value the value of the literal
    #  * @param dtype the type of the literal, None for old style "plain" literals
    # '''
    # ##@Override
    # # param Object value, RDFDatatype dtype
    # # result Literal
    # def createTypedLiteral(self, value, dtype):
    #     LiteralLabel ll = LiteralLabelFactory.createByValue(value, "", dtype)
    #     @SuppressWarnings("deprecation")
    #     Node n = NodeFactory.createLiteral(ll)
    #     return new LiteralImpl(n, this)
    #
    #
    # '''
    #  * Build a typed literal from its lexical form. The
    #  * lexical form will be parsed now and the value stored. If
    #  * the form is not legal this will throw an exception.
    #  *
    #  * @param lex     the lexical form of the literal
    #  * @param typeURI the uri of the type of the literal, None for old style "plain" literals
    #  * @throws DatatypeFormatException if lex is not a legal form of dtype
    # '''
    # ##@Override
    # # param String lex, String typeURI
    # # result Literal
    # def createTypedLiteral(self, lex, typeURI):
    #     RDFDatatype dt = TypeMapper.getInstance().getSafeTypeByName(typeURI)
    #     LiteralLabel ll = LiteralLabelFactory.create(lex, dt)
    #     @SuppressWarnings("deprecation")
    #     Node n = NodeFactory.createLiteral(ll)
    #     return new LiteralImpl(n, this)
    #
    #
    # '''
    #  * Build a typed literal from its value form.
    #  *
    #  * @param value   the value of the literal
    #  * @param typeURI the URI of the type of the literal, None for old style "plain" literals
    # '''
    # ##@Override
    # # param Object value, String typeURI
    # # result Literal
    # def createTypedLiteral(self, value, typeURI):
    #     RDFDatatype dt = TypeMapper.getInstance().getSafeTypeByName(typeURI)
    #     LiteralLabel ll = LiteralLabelFactory.createByValue(value, "", dt)
    #     @SuppressWarnings("deprecation")
    #     Node n = NodeFactory.createLiteral(ll)
    #     return new LiteralImpl(n, this)
    #
    #
    # '''
    #  * Build a typed literal label from its value form using
    #  * whatever datatype is currently registered as the the default
    #  * representation for this java class. No language tag is supplied.
    #  *
    #  * @param value the literal value to encapsulate
    # '''
    # ##@Override
    # # param Object value
    # # result Literal
    # def createTypedLiteral(self, value):
    #     # Catch special case of a Calendar which we want to act as if it were an XSDDateTime
    #     if (value instanceof Calendar)
    #         return self.createTypedLiteral((Calendar) value)
    #     LiteralLabel ll = LiteralLabelFactory.createTypedLiteral(value)
    #     @SuppressWarnings("deprecation")
    #     Node n = NodeFactory.createLiteral(ll)
    #     return new LiteralImpl(n, this)
    

    ##@Override
    # param String v
    # result Literal
    # def createLiteral(self, v):
    #     return self.createLiteral(v, "")
    #
    #
    # ##@Override
    # # param String v, String l
    # # result Literal
    # def createLiteral(self, v, l):
    #     return literal(v, l, false)
    #
    #
    # ##@Override
    # # param String v, boolean wellFormed
    # # result Literal
    # def createLiteral(self, v, wellFormed):
    #     return literal(v, "", wellFormed)
    

    # param String v, String lex, boolean wellFormed
    # result Literal
    def createLiteral(self, value, lex, wellFormed):
        return self.literal(value, lex, wellFormed)
    

    ##@Override
    # param Resource r, Property p, boolean o
    # result Statement
    # def createLiteralStatement(self, r, p, o):
    #     return self.createStatement(r, p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Resource r, Property p, long o
    # # result Statement
    # def createLiteralStatement(self, r, p, o):
    #     return self.createStatement(r, p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Resource r, Property p, int o
    # # result Statement
    # def createLiteralStatement(self, r, p, o):
    #     return self.createStatement(r, p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Resource r, Property p, char o
    # # result Statement
    # def createLiteralStatement(self, r, p, o):
    #     return self.createStatement(r, p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Resource r, Property p, float o
    # # result Statement
    # def createLiteralStatement(self, r, p, o):
    #     return self.createStatement(r, p, createTypedLiteral(o))
    #
    #
    # ##@Override
    # # param Resource r, Property p, double o
    # # result Statement
    # def createLiteralStatement(self, r, p, o):
    #     return self.createStatement(r, p, createTypedLiteral(o))
    

    ##@Override
    # param Resource r, Property p, String o
    # result Statement
    def createStatement(self, r, p, o):
        return self.createStatement(r, p, self.createLiteral(o))
    

    ##@Override
    # param Resource r, Property p, Object o
    # result Statement
    # def createLiteralStatement(self, r, p, o):
    #     return self.createStatement(r, p, asObject(o))
    

    ##@Override
    # param Resource r, Property p, String o, String lang, boolean wellFormed
    # result Statement
    # def createStatement(self, r, p, o, l, wellFormed):
    #     return self.createStatement(r, p, literal(o, l, wellFormed)
    

    ##@Override
    # param Resource r, Property p, String o, String l
    # result Statement
    # def createStatement(self, r, p, o, l):
    #     return self.createStatement(r, p, o, l, false)
    

    ##@Override
    # public Statement createStatement
    #         (Resource r, Property p, String o, String l, boolean wellFormed):
    #     return self.createStatement(r, p, literal(o, l, wellFormed))
    

    ##@Override
    # param 
    # result Bag
    def createBag(self):
        return self.createBag(None)
    

    ##@Override
    # param 
    # result Alt
    def createAlt(self):
        return self.createAlt(None)
    

    ##@Override
    # param 
    # result Seq
    def createSeq(self):
        return self.createSeq(None)
    

    '''
     * Answer a (the) new empty list
     * Until this is made the object or subject in the model, it will not appear in a written form.
     *
     * @return An RDF-encoded list of no elements (ie nil)
    '''
    ##@Override
    # param 
    # result RDFList
    def createList(self):
        pass
        # return getResource(RDF.nil.getURI()).as(RDFList.class)
    

    '''
     * <p>Answer a new list containing the resources from the given iterator, in order.</p>
     *
     * @param members An iterator, each value of which is expected to be an RDFNode.
     * @return An RDF-encoded list of the elements of the iterator
    '''
    ##@Override
    # param Iterator<? extends RDFNode> members
    # result RDFList
    # def createList(self, extends):
    #     if (!members.hasNext())
    #         return self.createList()
    #
    #     Resource root = createResource().addProperty(RDF.first, members.next())
    #     Resource last = root
    #     while (members.hasNext()):
    #         Resource rest = createResource().addProperty(RDF.first, members.next())
    #         last.addProperty(RDF.rest, rest)
    #         last = rest
    #
    #     last.addProperty(RDF.rest, RDF.nil)
    #
    #     return root.as(RDFList.class)
    


    '''
     * <p>Answer a new list containing the RDF nodes from the given array, in order</p>
     *
     * @param members An array of RDFNodes that will be the members of the list
     * @return An RDF-encoded list
    '''
    ##@Override
    # param RDFNode... members
    # result RDFList
    # def createList(self, members):
    #     return self.createList(Arrays.asList(members).iterator())
    

    ##@Override
    # param Node n
    # result RDFNode
    def getRDFNode(self, n):
        return self.asRDFNode(n)
    

    ##@Override
    # param String uri
    # result Resource
    def getResource(self, uri):
        return IteratorFactory.asResource(self.makeURI(uri), self)
    

    ##@Override
    # param String uri
    # result Property
    def getProperty(self, uri):
        if uri is None:
            raise NullPointerException(None)
        return IteratorFactory.asProperty(self.makeURI(uri), self)
    

    ##@Override
    # param String nameSpace, String localName
    # result Property
    # def getProperty(self, nameSpace, localName):
    #     return getProperty(nameSpace + localName)
    

    ##@Override
    # param String uri
    # result Seq
    def getSeq(self, uri):
        pass
        #return (Seq) IteratorFactory.asResource(makeURI(uri), Seq.class, this)
    

    ##@Override
    # param Resource r
    # result Seq
    # def getSeq(self, r):
    #     return r.inModel(this).as(Seq.class)
    

    ##@Override
    # param String uri
    # result Bag
    def getBag(self, uri):
        pass
        #return (Bag) IteratorFactory.asResource(makeURI(uri), Bag.class, this)
    

    ##@Override
    # param Resource r
    # result Bag
    # def getBag(self, r):
    #     return r.inModel(this).as(Bag.class)
    

    ##@Override
    # param String uri
    # result RDFList
    def getList(self, uri):
        pass
        #return (RDFList) IteratorFactory.asResource(makeURI(uri), RDFList.class, this)
    

    ##@Override
    # param Resource r
    # result RDFList
    # def getList(self, r):
    #     return r.inModel(this).as(RDFList.class)
    

    # param String uri
    # result Node
    def makeURI(self, uri):
        pass
        #return uri == None ? NodeFactory.createBlankNode() : NodeFactory.createURI(uri)
    

    ##@Override
    # param String uri
    # result Alt
    def getAlt(self, uri):
        pass
        #return (Alt) IteratorFactory.asResource(makeURI(uri), Alt.class, this)
    

    ##@Override
    # param Resource r
    # result Alt
    # def getAlt(self, r):
    #     return r.inModel(this).as(Alt.class)
    

    ##@Override
    # param 
    # result long
    def size(self):
        return self.graph.size()
    

    ##@Override
    # param 
    # result boolean
    def isEmpty(self):
        return self.graph.isEmpty()
    

    # param Set<String> set, Iterator<Node> it
    # result void
    def updateNamespace(self, set, it):
        while (it.hasNext()):
            #Node
            node = it.next()
            if (node.isURI()):
                #String
                uri = node.getURI()
                #String
                ns = uri.substring(0, Util.splitNamespaceXML(uri))
                # String ns = IteratorFactory.asResource( node, this ).getNameSpace()
                set.add(ns)
            
        
    

    # param 
    # result ExtendedIterator<Node>
    def listPredicates(self):
        return GraphUtil.listPredicates(self.graph, Node.ANY, Node.ANY)
    

    # param 
    # result Iterator<Node>
    # def listTypes(self):
    #     Set<Node> types = CollectionFactory.createHashedSet()
    #     ClosableIterator<Triple> it = graph.find(None, RDF.type.asNode(), None)
    #     while (it.hasNext()) types.add(it.next().getObject())
    #     return types.iterator()
    

    ##@Override
    # param 
    # result NsIterator
    # def listNameSpaces(self):
    #     Set<String> nameSpaces = CollectionFactory.createHashedSet()
    #     updateNamespace(nameSpaces, listPredicates())
    #     updateNamespace(nameSpaces, listTypes())
    #     return new NsIteratorImpl(nameSpaces.iterator(), nameSpaces)
    

    # param 
    # result PrefixMapping
    def getPrefixMapping(self):
        return self.getGraph().getPrefixMapping()
    

    ##@Override
    # param PrefixMapping other
    # result boolean
    def samePrefixMappingAs(self, other):
        return self.getPrefixMapping().samePrefixMappingAs(other)
    

    ##@Override
    # param 
    # result PrefixMapping
    # def lock(self):
    #     getPrefixMapping().lock()
    #     return self
    

    ##@Override
    # param String prefix, String uri
    # result Model
    def setNsPrefix(self, prefix, uri):
        self.getPrefixMapping().setNsPrefix(prefix, uri)
        return self
    

    ##@Override
    # param String prefix
    # result Model
    def removeNsPrefix(self, prefix):
        self.getPrefixMapping().removeNsPrefix(prefix)
        return self
    

    ##@Override
    # param 
    # result Model
    def clearNsPrefixMap(self):
        self.getPrefixMapping().clearNsPrefixMap()
        return self
    

    ##@Override
    # param PrefixMapping pm
    # result Model
    def setNsPrefixes(self, pm):
        self.getPrefixMapping().setNsPrefixes(pm)
        return self
    

    ##@Override
    # param Map<String, String> map
    # result Model
    # def setNsPrefixes(self, map):
    #     getPrefixMapping().setNsPrefixes(map)
    #     return self
    

    ##@Override
    # param PrefixMapping other
    # result Model
    def withDefaultMappings(self, other):
        self.getPrefixMapping().withDefaultMappings(other)
        return self
    

    ##@Override
    # param String prefix
    # result String
    def getNsPrefixURI(self, prefix):
        return self.getPrefixMapping().getNsPrefixURI(prefix)
    

    ##@Override
    # param String uri
    # result String
    def getNsURIPrefix(self, uri):
        return self.getPrefixMapping().getNsURIPrefix(uri)
    

    ##@Override
    # param 
    # result Map<String, String>
    def getNsPrefixMap(self):
        return self.getPrefixMapping().getNsPrefixMap()
    

    ##@Override
    # param String prefixed
    # result String
    def expandPrefix(self, prefixed):
        return self.getPrefixMapping().expandPrefix(prefixed)
    

    ##@Override
    # param String uri
    # result String
    def qnameFor(self, uri):
        return self.getPrefixMapping().qnameFor(uri)
    

    ##@Override
    # param String uri
    # result String
    def shortForm(self, uri):
        return self.getPrefixMapping().shortForm(uri)
    

    ##@Override
    # param 
    # result boolean
    def hasNoMappings(self):
        return self.getPrefixMapping().hasNoMappings()
    

    ##@Override
    # param 
    # result int
    def numPrefixes(self):
        return self.getPrefixMapping().numPrefixes()
    

    '''
     * Service method to update the namespaces of  a Model given the
     * mappings from prefix names to sets of URIs.
     * <p>
     * If the prefix maps to multiple URIs, then we discard it completely.
     *
     * @param m  Model who's namespace is to be updated
     * @param ns the namespace map to add to the Model
    '''
    # param Model m, Map<String, Set<String>> ns
    # result static void
    def addNamespaces(self, m, ns):
        pass
        # PrefixMapping pm = m
        # for (Map.Entry<String, Set<String>> e : ns.entrySet()):
        #     String key = e.getKey()
        #     Set<String> values = e.getValue()
        #     Set<String> niceValues = CollectionFactory.createHashedSet()
        #     for (String uri : values):
        #         if (PrefixMappingImpl.isNiceURI(uri)):
        #             niceValues.add(uri)
        #
        #
        #     if (niceValues.size() == 1):
        #         pm.setNsPrefix(key, niceValues.iterator().next())
            
        
    

    ##@Override
    # param 
    # result StmtIterator
    # def listStatements(self):
    #     return IteratorFactory.asStmtIterator(GraphUtil.findAll(graph), this)
    

    '''
     * add a Statement to this Model by adding its SPO components.
    '''
    ##@Override
    # param Statement s
    # result Model
    def add(self, s):
        self.graph.add(s.getSubject(), s.getPredicate(), s.getObject())
        return self
    

    '''
     * Add all the statements to the model by converting them to an array of corresponding
     * triples and removing those from the underlying graph.
    '''
    ##@Override
    # param Statement[] statements
    # result Model
    # def add(self, statements):
    #     GraphUtil.add(getGraph(), StatementImpl.asTriples(statements))
    #     return self
    

    '''
     * Add all the statements to the model by converting the list to an array of
     * Statement and removing that.
    '''
    ##@Override
    # param List<Statement> statements
    # result Model
    # def add(self, statements):
    #     GraphUtil.add(getGraph(), asTriples(statements))
    #     return self
    

    # param List<Statement> statements
    # result List<Triple>
    def asTriples(self, statements):
        pass
        # List<Triple> L = new ArrayList<>(statements.size())
        # for (Statement statement : statements):
        #     L.add(statement.asTriple())
        #
        # return L
    

    # param StmtIterator it
    # result Iterator<Triple>
    # def asTriples(self, it):
        # return it.mapWith(s -> s.asTriple())
    

    '''
     * remove all the Statements from the model by converting them to triples and
     * removing those triples from the underlying graph.
    '''
    ##@Override
    # param Statement[] statements
    # result Model
    # def remove(self, statements):
    #     GraphUtil.delete(getGraph(), StatementImpl.asTriples(statements))
    #     return self
    

    '''
     * Remove all the Statements from the model by converting the List to a
     * List(Statement) and removing that.
    '''
    ##@Override
    # param List<Statement> statements
    # result Model
    # def remove(self, statements):
    #     GraphUtil.delete(getGraph(), asTriples(statements))
    #     return self
    

    ##@Override
    # param Resource s, Property p, RDFNode o
    # result Model
    # def add(self, s, p, o):
    #     modelReifier.noteIfReified(s, p, o)
    #     graph.add(Triple.create(s.asNode(), p.asNode(), o.asNode()))
    #     return self
    

    '''
     * @return an iterator which delivers all the ReifiedStatements in this model
    '''
    ##@Override
    # param 
    # result RSIterator
    # def listReifiedStatements(self):
    #     return modelReifier.listReifiedStatements()
    

    '''
     * @return an iterator each of whose elements is a ReifiedStatement in this
     * model such that it's getStatement().equals( st )
    '''
    ##@Override
    # param Statement st
    # result RSIterator
    # def listReifiedStatements(self, st):
    #     return modelReifier.listReifiedStatements(st)
    

    '''
     * @return true iff this model has a reification of _s_ in some Statement
    '''
    ##@Override
    # param Statement s
    # result boolean
    # def isReified(self, s):
    #     return modelReifier.isReified(s)
    

    '''
     * get any reification of the given statement in this model make
     * one if necessary.
     *
     * @param s for which a reification is sought
     * @return a ReifiedStatement that reifies _s_
    '''
    ##@Override
    # param Statement s
    # result Resource
    # def getAnyReifiedStatement(self, s):
    #     return modelReifier.getAnyReifiedStatement(s)
    

    '''
     * remove any ReifiedStatements reifying the given statement
     *
     * @param s the statement who's reifications are to be discarded
    '''
    ##@Override
    # param Statement s
    # result void
    # def removeAllReifications(self, s):
    #     modelReifier.removeAllReifications(s)
    

    ##@Override
    # param ReifiedStatement rs
    # result void
    # def removeReification(self, rs):
    #     modelReifier.removeReification(rs)
    

    '''
     * create a ReifiedStatement that encodes _s_ and belongs to this Model.
    '''
    ##@Override
    # param Statement s
    # result ReifiedStatement
    # def createReifiedStatement(self, s):
    #     return modelReifier.createReifiedStatement(s)
    

    ##@Override
    # param String uri, Statement s
    # result ReifiedStatement
    # def createReifiedStatement(self, uri, s):
    #     return modelReifier.createReifiedStatement(uri, s)
    

    ##@Override
    # param Statement s
    # result boolean
    # def contains(self, s):
    #     return graph.contains(s.asTriple())
    

    ##@Override
    # param RDFNode r
    # result boolean
    def containsResource(self, r):
        return GraphUtil.containsNode(self.graph, r.asNode())
    

    ##@Override
    # param Resource s, Property p
    # result boolean
    # def contains(self, s, p):
    #     return self.contains(s, p, (RDFNode) None)
    

    ##@Override
    # param Resource s, Property p, RDFNode o
    # result boolean
    # def contains(self, s, p, o):
    #     return graph.contains(asNode(s), asNode(p), asNode(o))
    

    ##@Override
    # param Resource s, Property p
    # result Statement
    # def getRequiredProperty(self, s, p):
    #     Statement st = getProperty(s, p)
    #     if (st == None) raise PropertyNotFoundException(p)
    #     return st
    

    ##@Override
    # param Resource s, Property p, String lang
    # result Statement
    def getRequiredProperty(self, s, p, lang):
        #Statement
        st = self.getProperty(s, p, lang)
        if (st is None):
            raise PropertyNotFoundException(p)
        return st
    

    ##@Override
    # param Resource s, Property p
    # result Statement
    # def getProperty(self, s, p):
    #     StmtIterator ite = listStatements(s, p, (RDFNode) None)
    #     try:
    #         return ite.hasNext() ? ite.nextStatement() : None
    #      finally:
    #         ite.close()
        
    

    ##@Override
    # param Resource s, Property p, String lang
    # result Statement
    # def getProperty(self, s, p, lang):
    #     StmtIterator ite = listStatements(s, p, None, lang)
    #     try:
    #         return ite.hasNext() ? ite.nextStatement() : None
    #      finally:
    #         ite.close()
        
    

    # param RDFNode x
    # result static Node
    def asNode(self, x):
        #return x == None ? Node.ANY : x.asNode()
        return Node.ANY if x is None else x.asNode()
    

    # param RDFNode s, RDFNode p
    # result NodeIterator
    def listObjectsFor(self, s, p):
        #TODO 为什么要做二次封装 直接返回xit不行吗
        pass
        #ClosableIterator<Node> xit = GraphUtil.listObjects(graph, asNode(s), asNode(p))
        #return IteratorFactory.asRDFNodeIterator(xit, this)
    

    # param RDFNode p, RDFNode o
    # result ResIterator
    def listSubjectsFor(self, p, o):
        # TODO 为什么要做二次封装 直接返回xit不行吗
        pass
        # ClosableIterator<Node> xit = GraphUtil.listSubjects(graph, asNode(p), asNode(o))
        # return IteratorFactory.asResIterator(xit, this)
    

    ##@Override
    # param 
    # result ResIterator
    def listSubjects(self):
        return self.listSubjectsFor(None, None)
    

    ##@Override
    # param Property p
    # result ResIterator
    # def listResourcesWithProperty(self, p):
    #     return listSubjectsFor(p, None)
    

    ##@Override
    # param Property p
    # result ResIterator
    # def listSubjectsWithProperty(self, p):
    #     return listResourcesWithProperty(p)
    

    ##@Override
    # param Property p, RDFNode o
    # result ResIterator
    # def listResourcesWithProperty(self, p, o):
    #     return listSubjectsFor(p, o)
    

    ##@Override
    # param 
    # result NodeIterator
    def listObjects(self):
        return self.listObjectsFor(None, None)
    

    ##@Override
    # param Property p
    # result NodeIterator
    def listObjectsOfProperty(self, p):
        return self.listObjectsFor(None, p)
    

    ##@Override
    # param Resource s, Property p
    # result NodeIterator
    # def listObjectsOfProperty(self, s, p):
    #     return listObjectsFor(s, p)
    

    ##@Override
    # param final Selector selector
    # result StmtIterator
    # def listStatements(self, Selector):
    #     StmtIterator sts = IteratorFactory.asStmtIterator(findTriplesFrom(selector), this)
    #     return selector.isSimple()
    #             ? sts
    #             : new StmtIteratorImpl(sts.filterKeep(selector))
                
    

    '''
     * Answer an [extended] iterator which returns the triples in this graph which
     * are selected by the (S, P, O) triple in the selector, ignoring any special
     * tests it may do.
     *
     * @param s a Selector used to supply subject, predicate, and object
     * @return an extended iterator over the matching (S, P, O) triples
    '''
    # param Selector s
    # result ExtendedIterator<Triple>
    # def findTriplesFrom(self, s):
    #     return graph.find
    #             (asNode(s.getSubject()), asNode(s.getPredicate()), asNode(s.getObject()))
    

    ##@Override
    # param 
    # result boolean
    # def supportsTransactions(self):
    #     return getTransactionHandler().transactionsSupported()
    

    ##@Override
    # param 
    # result Model
    # def begin(self):
    #     getTransactionHandler().begin()
    #     return self
    

    ##@Override
    # param 
    # result Model
    # def abort(self):
    #     getTransactionHandler().abort()
    #     return self
    

    ##@Override
    # param 
    # result Model
    # def commit(self):
    #     getTransactionHandler().commit()
    #     return self
    

    # param 
    # result TransactionHandler
    # def getTransactionHandler(self):
    #     return getGraph().getTransactionHandler()
    

    ##@Override
    # param Runnable action
    # result void
    # def executeInTxn(self, action):
    #     getTransactionHandler().execute(action)
    

    '''
     * Execute the supplier <code>action</code> within a transaction. If it completes normally,
     * commit the transaction and return the result, otherwise abort the transaction.
    '''
    ##@Override
    # param Supplier<T> action
    # result <T> T
    # def calculateInTxn(self, action):
    #     return getTransactionHandler().calculate(action)
    

    ##@Override
    # param 
    # result boolean
    def independent(self):
        return True
    

    ##@Override
    # param 
    # result Resource
    # def createResource(self):
    #     return IteratorFactory.asResource(NodeFactory.createBlankNode(), this)
    

    ##@Override
    # param String uri
    # result Resource
    # def createResource(self, uri):
    #     return getResource(uri)
    

    ##@Override
    # param String uri
    # result Property
    def createProperty(self, uri):
        return self.getProperty(uri)
    

    ##@Override
    # param String nameSpace, String localName
    # result Property
    # def createProperty(self, nameSpace, localName):
    #     return getProperty(nameSpace, localName)
    

    '''
     * create a Statement from the given r, p, and o.
    '''
    ##@Override
    # param Resource r, Property p, RDFNode o
    # result Statement
    # def createStatement(self, r, p, o):
    #     return new StatementImpl(r, p, o, this)
    

    ##@Override
    # param String uri
    # result Bag
    # def createBag(self, uri):
    #     return (Bag) getBag(uri).addProperty(RDF.type, RDF.Bag)
    

    ##@Override
    # param String uri
    # result Alt
    # def createAlt(self, uri):
    #     return (Alt) getAlt(uri).addProperty(RDF.type, RDF.Alt)
    

    ##@Override
    # param String uri
    # result Seq
    # def createSeq(self, uri):
    #     return (Seq) getSeq(uri).addProperty(RDF.type, RDF.Seq)
    

    '''
     * Answer a Statement in this Model which encodes the given Triple.
     *
     * @param t a triple to wrap as a statement
     * @return a statement wrapping the triple and in this model
    '''
    ##@Override
    # param Triple t
    # result Statement
    def asStatement(self, t):
        from base.rdf.impl.StatementImpl import StatementImpl
        return StatementImpl.toStatement(t, self)
    

    # param Triple[] triples
    # result Statement[]
    # def asStatements(self, triples):
    #     Statement[] result = new Statement[triples.length]
    #     for (int i = 0 i < triples.length i += 1) result[i] = asStatement(triples[i])
    #     return result
    

    # param List<Triple> triples
    # result List<Statement>
    # def asStatements(self, triples):
    #     List<Statement> L = new ArrayList<>(triples.size())
    #     for (Triple triple : triples):
    #         L.add(asStatement(triple))
    #
    #     return L
    

    # param Graph g
    # result Model
    def asModel(self, g):
        return ModelCom(g)
    

    # param final Iterator<Triple> it
    # result StmtIterator
    # def asStatements(self, Iterator<Triple>):
    #     return new StmtIteratorImpl(new Map1Iterator<>(t -> asStatement(t), it))
    

    # param Container cont
    # result StmtIterator
    def listBySubject(self, cont):
        #return listStatements(cont, None, (RDFNode) None)
        return self.listStatements(cont, None, None)
    

    ##@Override
    # param 
    # result void
    def close(self):
        self.graph.close()
    

    ##@Override
    # param 
    # result boolean
    def isClosed(self):
        return self.graph.isClosed()
    

    ##@Override
    # param 
    # result boolean
    def supportsSetOperations(self):
        return True
    

    ##@Override
    # param Selector selector
    # result Model
    def query(self, selector):
        return self.createWorkModel().add(self.listStatements(selector))
    

    ##@Override
    # param Model model
    # result Model
    def union(self, model):
        return self.createWorkModel().add(self).add(model)
    

    '''
     * Intersect this with another model. As an attempt at optimisation, we try and ensure
     * we iterate over the smaller model first. Nowadays it's not clear that this is a good
     * idea, since <code>size()</code> can be expensive on database and inference
     * models.
     *
     * @see org.apache.jena.rdf.model.Model#intersection(org.apache.jena.rdf.model.Model)
    '''
    ##@Override
    # param Model other
    # result Model
    def intersection(self, other):
        return self.intersect(self, other) if self.size() < other.size() else self.intersect(other, self)
    

    '''
     * Answer a Model that is the intersection of the two argument models. The first
     * argument is the model iterated over, and the second argument is the one used
     * to check for membership. [So the first one should be "small" and the second one
     * "membership cheap".]
    '''
    # param Model smaller, Model larger
    # result static Model
    def intersect(self, smaller, larger):
        #Model
        result = self.createWorkModel()
        #StmtIterator
        it = smaller.listStatements()
        try:
            return self.addCommon(result, it, larger)
        finally:
            it.close()
        
    

    '''
     * Answer the argument result with all the statements from the statement iterator that
     * are in the other model added to it.
     *
     * @param result the Model to add statements to and return
     * @param it     an iterator over the candidate statements
     * @param other  the model that must contain the statements to be added
     * @return result, after the suitable statements have been added to it
    '''
    # param Model result, StmtIterator it, Model other
    # result static Model
    def addCommon(self, result, it, other):
        while (it.hasNext()):
            #Statement
            s = it.nextStatement()
            if (other.contains(s)):
                result.add(s)
        
        return result
    

    ##@Override
    # param Model model
    # result Model
    def difference(self, model):
        #Model
        resultModel = self.createWorkModel()
        #StmtIterator
        ite = None
        #Statement
        stmt = None
        try:
            ite = self.listStatements()
            while (ite.hasNext()):
                stmt = ite.nextStatement()
                if not model.contains(stmt):
                    resultModel.add(stmt)

            return resultModel
        finally:
            if ite is not None:
                ite.close()
            
        
    

    ##@Override
    # param 
    # result String
    def toString(self):
        return "<ModelCom  " + self.getGraph() + " | " + self.reifiedToString() + ">"
    

    # param 
    # result String
    def reifiedToString(self):
        return self.statementsToString(self.listStatements())
    

    # param StmtIterator it
    # result String
    def statementsToString(self, it):
        li = []
        while (it.hasNext()):
            li.append(str(it.nextStatement()))
        return ' '.join(li)
    

    '''
     * Answer whether or not these two graphs are isomorphic.
    '''
    ##@Override
    # param Model m
    # result boolean
    def isIsomorphicWith(self, m):
        #Graph
        L = self.getGraph()
        #Graph
        R = m.getGraph()
        return L.isIsomorphicWith(R)
    

    # param 
    # result synchronized Lock
    # def getModelLock(self):
    #     if (modelLock == None)
    #         modelLock = new LockMRSW()
    #     return modelLock
    

    ##@Override
    # param 
    # result synchronized Lock
    # def getLock(self):
    #     return getModelLock()
    


    ##@Override
    # param boolean requestReadLock
    # result void
    # def enterCriticalSection(self, requestReadLock):
    #     self.getModelLock().enterCriticalSection(requestReadLock)
    

    ##@Override
    # param 
    # result void
    # def leaveCriticalSection(self):
    #     self.getModelLock().leaveCriticalSection()
    

    '''
     * Register the listener with this model by registering its GraphListener
     * adaption with the underlying Graph.
     *
     * @param listener A ModelChangedListener to register for model events
     * @return self model, for cascading
    '''
    ##@Override
    # param ModelChangedListener listener
    # result Model
    # def register(self, listener):
    #     getGraph().getEventManager().register(adapt(listener))
    #     return self
    

    '''
     * Unregister the listener from this model by unregistering its GraphListener
     * adaption from the underlying Graph.
     *
     * @param listener A ModelChangedListener to unregister from model events
     * @return self model, for cascading
    '''
    ##@Override
    # param ModelChangedListener listener
    # result Model
    # def unregister(self, listener):
    #     getGraph().getEventManager().unregister(adapt(listener))
    #     return self
    

    '''
     * Answer a GraphListener that, when fed graph-level update events,
     * fires the corresponding model-level event handlers in <code>L</code>.
     *
     * @param L a model listener to be wrapped as a graph listener
     * @return a graph listener wrapping L
     * @see ModelListenerAdapter
    '''
    # param final ModelChangedListener L
    # result GraphListener
    # def adapt(self, ModelChangedListener):
    #     return ModelListenerAdapter(this, L)
    

    ##@Override
    # param Object e
    # result Model
    # def notifyEvent(self, e):
    #     getGraph().getEventManager().notifyEvent(getGraph(), e)
    #     return self